/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-04-13     starry       the first version
 */
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <U8g2lib.h>
#include <stdio.h>
#include <board.h>
#include <drv_soft_i2c.h>
#include <webclient.h>
#include "cJSON_Utils.h"

#include <string.h>
#define GET_HEADER_BUFSZ               1024
#define GET_RESP_BUFSZ                 1024

#define GET_LOCAL_URI                  "http://api.seniverse.com/v3/weather/now.json?key=SZskA-VCQ8UWQ79Zj&location=Xiangtan"

class webWeather
{
public:
      webWeather(char *weburi)
      {
        // *uri = RT_NULL;
        // GET_LOCAL_URI
        buffer = RT_NULL;
        m_uri = RT_NULL;
        m_JSON= RT_NULL;
        m_weather = RT_NULL;
        m_temperature = RT_NULL;
        m_uri = web_strdup(weburi);
        if(m_uri == RT_NULL)
        {
            rt_kprintf("no memory for create get request uri buffer.\n");
            
        }
        
      }
      ~webWeather()
      {
          web_free(m_uri);
      }
      int webWeatherclient_get_comm();//const char *uri
      int weather_cJSON_Tran();
      void Print_Info_weather();
      void Print_Info_temperature();
      char *Get_Weather();
      char *Get_Temperature();
      char *Get_Rigion();
      void Set_Weather(const char *weather);
      void Set_Temperature(const char *temperature);
      void Set_Region(const char *region);
private:
      char *m_uri;
      char *m_JSON;
      char *m_weather;
      char *m_temperature;
      char *m_region;
      char *buffer;
};






#define OLED_I2C_PIN_SCL                    GET_PIN(B, 13)//7   // PA7
#define OLED_I2C_PIN_SDA                    GET_PIN(B, 15)//20  // PB4

static U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0,\
                                         /* clock=*/ OLED_I2C_PIN_SCL,\
                                         /* data=*/ OLED_I2C_PIN_SDA,\
                                         /* reset=*/ U8X8_PIN_NONE);
static webWeather starry_weather(GET_LOCAL_URI);


#define SUN 0
#define SUN_CLOUD  1
#define CLOUD 2
#define RAIN 3
#define THUNDER 4

static void drawWeatherSymbol(u8g2_uint_t x, u8g2_uint_t y, uint8_t symbol)
{
  // fonts used:
  // u8g2_font_open_iconic_embedded_6x_t
  // u8g2_font_open_iconic_weather_6x_t
  // encoding values, see: https://github.com/olikraus/u8g2/wiki/fntgrpiconic

  switch(symbol)
  {
    case SUN:
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 69);
      break;
    case SUN_CLOUD:
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 65);
      break;
    case CLOUD:
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 64);
      break;
    case RAIN:
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 67);
      break;
    case THUNDER:
      u8g2.setFont(u8g2_font_open_iconic_embedded_6x_t);
      u8g2.drawGlyph(x, y, 67);
      break;
  }
}

static void drawWeather(uint8_t symbol, int degree)
{
  drawWeatherSymbol(0, 63, symbol);
  u8g2.setFont(u8g2_font_logisoso32_tf);
  u8g2.setCursor(55, 63);
  u8g2.print(degree);
  u8g2.print("C");
}
static void drawHumidity(uint8_t symbol, int humidity)
{
  drawWeatherSymbol(0, 63, symbol);
  u8g2.setFont(u8g2_font_logisoso32_tf);
  u8g2.setCursor(55, 63);
  u8g2.print(humidity);
  u8g2.print("%");
}



int weather_str_get(char *str)
{   if(0==rt_strcasecmp (str,"晴"))
    {
        return SUN;
    }
    else if(0==rt_strcasecmp (str,"多云"))
    {
        return SUN_CLOUD;
    }
    else if(0==rt_strcasecmp (str,"阴"))
    {
        return CLOUD;
    }
    else if(0==rt_strcasecmp (str,"雨"))
    {
        return RAIN;
    }
    else
    {
        return SUN;
    }

}

void oled_display(void*)
{
    u8g2.begin();
    u8g2.clearBuffer();

    u8g2.setFont(u8g2_font_logisoso32_tf);
    u8g2.setCursor(48+3, 42);
    u8g2.print("Hi~");     // requires enableUTF8Print()

    u8g2.setFont(u8g2_font_6x13_tr);            // choose a suitable font
    u8g2.drawStr(30, 60, "By starry");   // write something to the internal memory
    u8g2.sendBuffer();

    rt_thread_mdelay(1000);
    starry_weather.webWeatherclient_get_comm();
    starry_weather.weather_cJSON_Tran();
    starry_weather.Print_Info_weather();
    starry_weather.Print_Info_temperature();
    rt_thread_mdelay(1000);

    int status = 0;
    char mstr[3];
    char hstr[3];
    char date_buf[15];
    time_t now;
    struct tm *p;
    int min = 0, hour = 0,year=0,month=0,day=0;
    int temperature = 0,humidity = 0;
    temperature= atoi(starry_weather.Get_Temperature());
    while(1)
    {
        switch(status)
        {
            case 0:
                now = time(RT_NULL);
                p=gmtime((const time_t*) &now);
                hour = p->tm_hour;
                min = p->tm_min;
                year=p->tm_year;
                month=p->tm_mon;
                day=p->tm_mday;
                sprintf(mstr, "%02d", min);
                sprintf(hstr, "%02d", hour);
                sprintf(date_buf,"%04d-%02d-%02d",year+1900,month+1,day);
                u8g2.firstPage();
                do {
                     u8g2.setFont(u8g2_font_fub11_tf);
                     u8g2.drawStr(10,12,date_buf);

                     u8g2.setFont(u8g2_font_logisoso42_tn);
                     u8g2.drawStr(0,63,hstr);
                     u8g2.drawStr(50,63,":");
                     u8g2.drawStr(67,63,mstr);
                   } while ( u8g2.nextPage() );


                rt_thread_mdelay(5000);
                status = 1;
                break;
           case 1:

               u8g2.clearBuffer();
               drawWeather(weather_str_get(starry_weather.Get_Weather()), temperature);
               u8g2.sendBuffer();
               rt_thread_mdelay(5000);
               status = 0;
               break;

        }
    }
}
//MSH_CMD_EXPORT(oled_display, oled start);



int Rtc_test(void)
{
    rt_thread_t tid = rt_thread_create("oledth", oled_display, NULL, 2048, 11, 11);
    rt_thread_startup(tid);

    return RT_EOK;
}
INIT_APP_EXPORT(Rtc_test);

int webWeather::weather_cJSON_Tran()
{
    cJSON *json,*arrayItem,*object,*subobject,*item;
    int size;
    json = cJSON_Parse(m_JSON);//解析JSON数据包
        if(json == NULL)          //检测JSON数据包是否存在语法上的错误，返回NULL表示数据包无效
        {
            rt_kprintf("Error before: [%s]\r\n",cJSON_GetErrorPtr()); //打印数据包语法错误的位置
        }
        else
        {
            if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL); //匹配字符串"results",获取数组内容
            {
                size = cJSON_GetArraySize(arrayItem);     //获取数组中对象个数
                rt_kprintf(" : size=%d\n",size);

                if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)//获取父对象内容
                {
                    rt_kprintf("--------------------------------Now Weather Data Begin------------------------------\r\n");
                    /* 匹配子对象1 */
                    if((subobject = cJSON_GetObjectItem(object,"location")) != NULL)
                    {

                        rt_kprintf("---------------------------------subobject1-------------------------------\r\n");
                        if((item = cJSON_GetObjectItem(subobject,"id")) != NULL)
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string,item->valuestring);
                        }
                        if((item = cJSON_GetObjectItem(subobject,"name")) != NULL) //地名--需要用到的数据
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string,item->valuestring);
                            Set_Region(item->valuestring);
                        }
                        if((item = cJSON_GetObjectItem(subobject,"country")) != NULL)
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string,item->valuestring);
                        }
                        if((item = cJSON_GetObjectItem(subobject,"path")) != NULL)
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string,item->valuestring);
                        }
                        if((item = cJSON_GetObjectItem(subobject,"timezone")) != NULL)
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string,item->valuestring);
                        }
                        if((item = cJSON_GetObjectItem(subobject,"timezone_offset")) != NULL)
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string,item->valuestring);
                        }
                    }
                    /* 匹配子对象2 */
                    if((subobject = cJSON_GetObjectItem(object,"now")) != NULL)
                    {
                        rt_kprintf("---------------------------------subobject2-------------------------------\r\n");
                        if((item = cJSON_GetObjectItem(subobject,"text")) != NULL)//天气预报文字--需要用到的数据
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string,item->valuestring);
                            // m_weather=item->valuestring;
                            Set_Weather(item->valuestring);
                        }
                        if((item = cJSON_GetObjectItem(subobject,"code")) != NULL)//天气预报代码--需要用到的数据
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string, item->valuestring);

                        }
                        if((item = cJSON_GetObjectItem(subobject,"temperature")) != NULL) //温度--需要用到的数据
                        {
                            rt_kprintf(" : %s:%s\r\n",item->string, item->valuestring);
                            // m_temperature=item->valuestring;
                            Set_Temperature(item->valuestring);
                        }
                    }
                    /* 匹配子对象3 */
                    if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL)
                    {
                        rt_kprintf("---------------------------------subobject3-------------------------------\r\n");
                        rt_kprintf(" : %s:%s\r\n",subobject->string,subobject->valuestring);
                    }
                    rt_kprintf("--------------------------------Now Weather Data End--------------------------------\r\n");
                }
            }
        }

      if (buffer)
      {
          web_free(buffer);
      }
        cJSON_Delete(json); //释放cJSON_Parse()分配出来的内存空间
        return 0;
}
int webWeather::webWeatherclient_get_comm()
{
    const char *uri=m_uri;
    struct webclient_session* session = RT_NULL;
    
    int index, ret = 0;
    int bytes_read, resp_status;
    int content_length = -1;

    buffer = (char *) web_malloc(GET_RESP_BUFSZ);
    if (buffer == RT_NULL)
        {
            rt_kprintf("no memory for receive buffer.\n");
            ret = -RT_ENOMEM;
            goto __exit;

        }
    /* create webclient session and set header response size */
    session = webclient_session_create(GET_HEADER_BUFSZ);
    if (session == RT_NULL)
    {
        ret = -RT_ENOMEM;
        goto __exit;
    }

    /* send GET request by default header */
    if ((resp_status = webclient_get(session, uri)) != 200)
    {
        rt_kprintf("webclient GET request failed, response(%d) error.\n", resp_status);
        ret = -RT_ERROR;
        goto __exit;
    }

    rt_kprintf("webclient get response data: \n");

    content_length = webclient_content_length_get(session);
    if (content_length < 0)
    {
        rt_kprintf("webclient GET request type is chunked.\n");
        do
        {
            bytes_read = webclient_read(session, (void *)buffer, GET_RESP_BUFSZ);
            if (bytes_read <= 0)
            {
                break;
            }

            for (index = 0; index < bytes_read; index++)
            {
                rt_kprintf("%c", buffer[index]);
            }
        } while (1);

        rt_kprintf("\n");
    }
    else
    {
        int content_pos = 0;

        do
        {
            bytes_read = webclient_read(session, (void *)buffer,
                    content_length - content_pos > GET_RESP_BUFSZ ?
                            GET_RESP_BUFSZ : content_length - content_pos);
            if (bytes_read <= 0)
            {
                break;
            }

            for (index = 0; index < bytes_read; index++)
            {
                rt_kprintf("%c", buffer[index]);
            }
            // weather_cJSON_Tran(buffer);
            m_JSON=buffer;
            content_pos += bytes_read;
        } while (content_pos < content_length);

        rt_kprintf("\n");
    }
        __exit:
      if (session)
      {
          webclient_close(session);
      }



    return ret;

}
void webWeather::Print_Info_weather()
{
    rt_kprintf("weather : %s\n",m_weather);
}
void webWeather::Print_Info_temperature()
{
    rt_kprintf("temperature : %s\n",m_temperature);
}
char *webWeather::Get_Weather()
{
    return m_weather;
}
char *webWeather::Get_Temperature()
{
    return m_temperature;
}
void webWeather::Set_Weather(const char *weather)
{
    m_weather =(char *)weather;
}
void webWeather::Set_Temperature(const char *temperature)
{
  m_temperature = (char *)temperature;
}
void webWeather::Set_Region(const char *region)
{
  m_region = (char *)region;
}
